#include "pch.hpp"
#include "GraphicsWidget.hpp"
#include "Application.hpp"

using namespace QtUi;




GraphicsWidget::GraphicsWidget(QWidget* parent)
	: m_winIdChanged(false)
	, m_engine(createEngine())
	, m_videoDevice(m_engine->videoDevice())
	, m_timer(this)
{
	connect(&m_timer, SIGNAL(timeout()), SLOT(onUpdate()));
	m_timer.start(1000/60);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

GraphicsWidget::GraphicsWidget(const EngineInfo& info, QWidget* parent)
	: m_winIdChanged(false)
	, m_engine(createEngine(info))
	, m_videoDevice(m_engine->videoDevice())
	, m_timer(this)
{
	connect(&m_timer, SIGNAL(timeout()), SLOT(onUpdate()));
	m_timer.start(1000/60);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

GraphicsWidget::~GraphicsWidget()
{}
///////////////////////////////////////////////////////////////////////////////////////////////////




Engine::IEngine::ptr GraphicsWidget::engine() const
{
	return m_engine;
}
///////////////////////////////////////////////////////////////////////////////////////////////////




void GraphicsWidget::onUpdate()
{
	if(m_winIdChanged)
	{
		m_engine->changeWindow((HWND)winId());
		m_winIdChanged = false;
	}

	try
	{
		m_engine->update();
	}
	catch(boostext::exception& e)
	{
		// The engine shouldn't throw during the update call
		// If it does then there's something wrong which should
		// terminate the application right away
		BOOSTEXT_THROW(critical_exception(format("Exception caught during engine update: %1%") % e.what())
			<< debug_info_e(e)
		);
	}
}
///////////////////////////////////////////////////////////////////////////////////////////////////

bool GraphicsWidget::event(QEvent* event)
{
	if(event->type() == QEvent::WinIdChange)
	{
		m_winIdChanged = true;
	}

	return QWidget::event(event);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void GraphicsWidget::resizeEvent(QResizeEvent* event)
{
	if(m_videoDevice)
	{
		m_engine->resize(event->size().width(), event->size().height());
	}

	event->accept();
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void GraphicsWidget::contextMenuEvent(QContextMenuEvent* event)
{
	//event->accept();
}
///////////////////////////////////////////////////////////////////////////////////////////////////

Engine::IEngine::ptr GraphicsWidget::createEngine()
{
	DisplayMode mode;
	mode.width  = width();
	mode.height = height();
	mode.aspect = AspectCustom;
	mode.windowMode = WindowMode::Windowed;

	EngineInfo info(mode);
	info.window = (HWND)winId();
	info.serviceProvider = Application::instance()->serviceProvider();

	verify(info.window != nullptr);

	return Engine::IEngine::create(info);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

Engine::IEngine::ptr GraphicsWidget::createEngine(EngineInfo info)
{
	DisplayMode mode;
	mode.width  = width();
	mode.height = height();
	mode.aspect = AspectCustom;
	mode.windowMode = WindowMode::Windowed;

	info.displayMode = mode;
	info.window = (HWND)winId();
	info.serviceProvider = Application::instance()->serviceProvider();

	verify(info.window != nullptr);

	return Engine::IEngine::create(info);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
